/*
 * sendinfocommand.cpp
 *
 *  Created on: Aug 10, 2010
 *      Author: kevin
 */

#include "sendinfocommand.h"
#include <iostream>
#include <sstream>
#include <string>
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Element.h>
#include <Poco/DOM/DOMWriter.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/Net/DatagramSocket.h>

using Poco::XML::DOMParser;
using Poco::XML::Element;
using Poco::XML::DOMWriter;
using Poco::XML::NodeList;
using Poco::Net::DatagramSocket;
using namespace std;

namespace Commands
{
	const string SendInfoCommand::NAME = "SendInfo";

	SendInfoCommand::SendInfoCommand(SocketAddress addr, NodeData* node)
		: NodeCommand(node)
		  , _addr(addr)
	{
		cout << "SendInfoCommand :: Constructing SendInfoCommand" << endl;
	}

	SendInfoCommand::~SendInfoCommand()
	{
		cout << "SendInfoCommand :: Destroying SendInfoCommand" << endl;
	}

	CommandCreator SendInfoCommand::creator()
	{
		cout << "SendInfoCommand :: creator" << endl;
		return SendInfoCommand::makeCommand;
	}

	void SendInfoCommand::execute()
	{
		cout << "SendInfoCommand :: Execute" << endl;
		cout << "SendInfoCommand :: Execute :: Sock" << remote().toString() << endl;
		ostringstream ss;
		ss << nodeId() << ":" << slavePort();
		DatagramSocket sock;
		SocketAddress addr(remote().host(), _addr.port());
		sock.sendTo(ss.str().c_str(), ss.str().size(), addr);
	}

	string SendInfoCommand::repr()
	{
		cout << "SendInfoCommand :: repr" << endl;
		ostringstream out;
		DOMWriter w;
		w.writeNode(out, toXML());
		return out.str();
	}

	Document* SendInfoCommand::toXML( Document* )
	{
		cout << "SendInfoCommand :: toXML"<< endl;
		Document* doc = new Document();

		//What do we want to put
		Element* file = doc->createElement("node");
		file->setAttribute("address", _addr.toString());
		doc->appendChild(file);

		return Command::toXML(doc);
	}

	string SendInfoCommand::name()
	{
		cout << "SendInfoCommand :: name" << endl;
		return string(SendInfoCommand::NAME);
	}

	Command* SendInfoCommand::makeCommand(string r, void* s)
	{
		cout << "SendInfoCommand :: makeCommand" << endl;
		//FIXME should be just a socket, socketaddress or nodedata
		NodeData* data = (NodeData*)s;
		DOMParser parser;
		Document* doc = parser.parseString(r);
		//Get the ip address
		string ip = ((Element*)(doc->getElementsByTagName("node")->item(0)))->getAttribute("address");
		cout << "SendInfoCommand :: Creating Command :: " << ip << endl;
		//TODO The SocketAddress should be more sensible here...
		//try{
			cout << "SendInfoCommand :: Returning SendInfoCommand " << endl;
			SocketAddress addr(ip);
			return new SendInfoCommand(addr, data);
		//} catch( Poco::Exception e){
		//	cout << e.displayText() << endl;
		//}
	}
}
